<?php

namespace App\Services;

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;

class ValidationService
{
    /**
     * 验证用户数据
     */
    public function validateUser(array $data, bool $isUpdate = false): array
    {
        $rules = [
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:users,email',
            'password' => 'required|string|min:8|confirmed',
            'phone' => 'nullable|string|max:20',
            'is_active' => 'boolean',
        ];

        if ($isUpdate) {
            $rules['email'] = 'required|email|max:255|unique:users,email,' . $data['id'];
            $rules['password'] = 'nullable|string|min:8|confirmed';
        }

        return $this->validate($data, $rules, [
            'name.required' => '姓名不能为空',
            'email.required' => '邮箱不能为空',
            'email.email' => '邮箱格式不正确',
            'email.unique' => '邮箱已被使用',
            'password.required' => '密码不能为空',
            'password.min' => '密码至少8位',
            'password.confirmed' => '密码确认不匹配',
        ]);
    }

    /**
     * 验证商品数据
     */
    public function validateProduct(array $data, bool $isUpdate = false): array
    {
        $rules = [
            'name' => 'required|string|max:255',
            'slug' => 'required|string|max:255|unique:products,slug',
            'description' => 'nullable|string',
            'price' => 'required|numeric|min:0',
            'stock_quantity' => 'required|integer|min:0',
            'is_active' => 'boolean',
            'is_featured' => 'boolean',
            'category_ids' => 'required|array|min:1',
            'category_ids.*' => 'exists:categories,id',
        ];

        if ($isUpdate) {
            $rules['slug'] = 'required|string|max:255|unique:products,slug,' . $data['id'];
        }

        return $this->validate($data, $rules, [
            'name.required' => '商品名称不能为空',
            'slug.required' => '商品别名不能为空',
            'slug.unique' => '商品别名已被使用',
            'price.required' => '价格不能为空',
            'price.numeric' => '价格必须是数字',
            'price.min' => '价格不能小于0',
            'stock_quantity.required' => '库存不能为空',
            'stock_quantity.integer' => '库存必须是整数',
            'stock_quantity.min' => '库存不能小于0',
            'category_ids.required' => '请选择商品分类',
            'category_ids.min' => '至少选择一个分类',
        ]);
    }

    /**
     * 验证订单数据
     */
    public function validateOrder(array $data): array
    {
        $rules = [
            'address_id' => 'required|exists:user_addresses,id',
            'payment_method' => 'required|string|in:alipay,wechat,cod',
            'notes' => 'nullable|string|max:500',
        ];

        return $this->validate($data, $rules, [
            'address_id.required' => '请选择收货地址',
            'address_id.exists' => '收货地址不存在',
            'payment_method.required' => '请选择支付方式',
            'payment_method.in' => '支付方式无效',
            'notes.max' => '订单备注不能超过500个字符',
        ]);
    }

    /**
     * 验证购物车数据
     */
    public function validateCartItem(array $data): array
    {
        $rules = [
            'product_id' => 'required|exists:products,id',
            'variant_id' => 'nullable|exists:product_variants,id',
            'quantity' => 'required|integer|min:1|max:99',
        ];

        return $this->validate($data, $rules, [
            'product_id.required' => '请选择商品',
            'product_id.exists' => '商品不存在',
            'variant_id.exists' => '商品规格不存在',
            'quantity.required' => '请输入数量',
            'quantity.integer' => '数量必须是整数',
            'quantity.min' => '数量不能少于1',
            'quantity.max' => '数量不能超过99',
        ]);
    }

    /**
     * 验证售后申请数据
     */
    public function validateAfterSales(array $data): array
    {
        $rules = [
            'order_id' => 'required|exists:orders,id',
            'type' => 'required|in:return,refund,exchange',
            'reason' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'images' => 'nullable|array|max:5',
            'images.*' => 'image|mimes:jpeg,png,jpg,gif|max:2048',
            'items' => 'required|array|min:1',
            'items.*.order_item_id' => 'required|exists:order_items,id',
            'items.*.quantity' => 'required|integer|min:1',
        ];

        return $this->validate($data, $rules, [
            'order_id.required' => '请选择订单',
            'order_id.exists' => '订单不存在',
            'type.required' => '请选择售后类型',
            'type.in' => '售后类型无效',
            'reason.required' => '请填写售后原因',
            'reason.max' => '售后原因不能超过255个字符',
            'description.max' => '详细描述不能超过1000个字符',
            'images.array' => '图片格式错误',
            'images.max' => '最多只能上传5张图片',
            'images.*.image' => '文件必须是图片',
            'images.*.mimes' => '图片格式必须是jpeg、png、jpg或gif',
            'images.*.max' => '图片大小不能超过2MB',
            'items.required' => '请选择要申请售后的商品',
            'items.min' => '至少选择一个商品',
            'items.*.order_item_id.required' => '请选择商品',
            'items.*.order_item_id.exists' => '商品不存在',
            'items.*.quantity.required' => '请输入数量',
            'items.*.quantity.integer' => '数量必须是整数',
            'items.*.quantity.min' => '数量不能少于1',
        ]);
    }

    /**
     * 验证地址数据
     */
    public function validateAddress(array $data, bool $isUpdate = false): array
    {
        $rules = [
            'name' => 'required|string|max:255',
            'phone' => 'required|string|max:20',
            'province_id' => 'required|exists:provinces,id',
            'city_id' => 'required|exists:cities,id',
            'district_id' => 'required|exists:districts,id',
            'address' => 'required|string|max:500',
            'is_default' => 'boolean',
        ];

        return $this->validate($data, $rules, [
            'name.required' => '收货人姓名不能为空',
            'phone.required' => '联系电话不能为空',
            'province_id.required' => '请选择省份',
            'province_id.exists' => '省份不存在',
            'city_id.required' => '请选择城市',
            'city_id.exists' => '城市不存在',
            'district_id.required' => '请选择区县',
            'district_id.exists' => '区县不存在',
            'address.required' => '详细地址不能为空',
            'address.max' => '详细地址不能超过500个字符',
        ]);
    }

    /**
     * 验证物流公司数据
     */
    public function validateLogisticsCompany(array $data, bool $isUpdate = false): array
    {
        $rules = [
            'name' => 'required|string|max:255',
            'code' => 'required|string|max:50|unique:logistics_companies,code',
            'website' => 'nullable|url|max:255',
            'phone' => 'nullable|string|max:20',
            'is_active' => 'boolean',
            'sort_order' => 'integer|min:0',
        ];

        if ($isUpdate) {
            $rules['code'] = 'required|string|max:50|unique:logistics_companies,code,' . $data['id'];
        }

        return $this->validate($data, $rules, [
            'name.required' => '物流公司名称不能为空',
            'code.required' => '物流公司代码不能为空',
            'code.unique' => '物流公司代码已被使用',
            'website.url' => '网站地址格式不正确',
            'sort_order.integer' => '排序必须是整数',
            'sort_order.min' => '排序不能小于0',
        ]);
    }

    /**
     * 验证系统设置数据
     */
    public function validateSystemSetting(array $data): array
    {
        $rules = [
            'key' => 'required|string|max:255',
            'value' => 'required|string',
            'description' => 'nullable|string|max:500',
            'type' => 'required|in:string,number,boolean,json',
        ];

        return $this->validate($data, $rules, [
            'key.required' => '设置键不能为空',
            'value.required' => '设置值不能为空',
            'type.required' => '设置类型不能为空',
            'type.in' => '设置类型无效',
        ]);
    }

    /**
     * 验证文件上传
     */
    public function validateFileUpload(array $data, string $type = 'image'): array
    {
        $rules = match($type) {
            'image' => [
                'file' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
            ],
            'document' => [
                'file' => 'required|file|mimes:pdf,doc,docx|max:10240',
            ],
            'excel' => [
                'file' => 'required|file|mimes:xlsx,xls,csv|max:10240',
            ],
            default => [
                'file' => 'required|file|max:10240',
            ],
        };

        $messages = match($type) {
            'image' => [
                'file.required' => '请选择图片文件',
                'file.image' => '文件必须是图片',
                'file.mimes' => '图片格式必须是jpeg、png、jpg或gif',
                'file.max' => '图片大小不能超过2MB',
            ],
            'document' => [
                'file.required' => '请选择文档文件',
                'file.mimes' => '文档格式必须是pdf、doc或docx',
                'file.max' => '文档大小不能超过10MB',
            ],
            'excel' => [
                'file.required' => '请选择Excel文件',
                'file.mimes' => '文件格式必须是xlsx、xls或csv',
                'file.max' => '文件大小不能超过10MB',
            ],
            default => [
                'file.required' => '请选择文件',
                'file.max' => '文件大小不能超过10MB',
            ],
        };

        return $this->validate($data, $rules, $messages);
    }

    /**
     * 验证分页参数
     */
    public function validatePagination(array $data): array
    {
        $rules = [
            'page' => 'integer|min:1',
            'per_page' => 'integer|min:1|max:100',
            'sort' => 'string|in:created_at,updated_at,name,price',
            'order' => 'string|in:asc,desc',
        ];

        return $this->validate($data, $rules, [
            'page.integer' => '页码必须是整数',
            'page.min' => '页码不能小于1',
            'per_page.integer' => '每页数量必须是整数',
            'per_page.min' => '每页数量不能小于1',
            'per_page.max' => '每页数量不能超过100',
            'sort.in' => '排序字段无效',
            'order.in' => '排序方向无效',
        ]);
    }

    /**
     * 验证搜索参数
     */
    public function validateSearch(array $data): array
    {
        $rules = [
            'keyword' => 'nullable|string|max:255',
            'category' => 'nullable|string|max:255',
            'min_price' => 'nullable|numeric|min:0',
            'max_price' => 'nullable|numeric|min:0|gte:min_price',
            'status' => 'nullable|string|max:50',
            'date_from' => 'nullable|date',
            'date_to' => 'nullable|date|after_or_equal:date_from',
        ];

        return $this->validate($data, $rules, [
            'keyword.max' => '关键词不能超过255个字符',
            'category.max' => '分类不能超过255个字符',
            'min_price.numeric' => '最低价格必须是数字',
            'min_price.min' => '最低价格不能小于0',
            'max_price.numeric' => '最高价格必须是数字',
            'max_price.min' => '最高价格不能小于0',
            'max_price.gte' => '最高价格不能小于最低价格',
            'status.max' => '状态不能超过50个字符',
            'date_from.date' => '开始日期格式不正确',
            'date_to.date' => '结束日期格式不正确',
            'date_to.after_or_equal' => '结束日期不能早于开始日期',
        ]);
    }

    /**
     * 执行验证
     */
    private function validate(array $data, array $rules, array $messages = []): array
    {
        $validator = Validator::make($data, $rules, $messages);

        if ($validator->fails()) {
            throw new ValidationException($validator);
        }

        return $validator->validated();
    }

    /**
     * 验证权限
     */
    public function validatePermission(string $permission, $user = null): bool
    {
        $user = $user ?? auth()->user();
        
        if (!$user) {
            return false;
        }

        return $user->can($permission);
    }

    /**
     * 验证资源所有权
     */
    public function validateOwnership($resource, string $userIdField = 'user_id', $userId = null): bool
    {
        $userId = $userId ?? auth()->id();
        
        if (!$userId) {
            return false;
        }

        if (is_object($resource)) {
            return $resource->$userIdField == $userId;
        }

        if (is_array($resource)) {
            return ($resource[$userIdField] ?? null) == $userId;
        }

        return false;
    }

    /**
     * 验证业务规则
     */
    public function validateBusinessRule(string $rule, array $data): bool
    {
        return match($rule) {
            'order_can_cancel' => $this->canOrderCancel($data),
            'order_can_apply_after_sales' => $this->canOrderApplyAfterSales($data),
            'product_has_stock' => $this->productHasStock($data),
            'cart_item_valid' => $this->cartItemValid($data),
            default => false,
        };
    }

    private function canOrderCancel(array $data): bool
    {
        $order = $data['order'] ?? null;
        return $order && in_array($order->status, ['pending', 'processing']);
    }

    private function canOrderApplyAfterSales(array $data): bool
    {
        $order = $data['order'] ?? null;
        return $order && in_array($order->status, ['processing', 'shipped', 'delivered']) 
            && $order->payment_status === 'paid';
    }

    private function productHasStock(array $data): bool
    {
        $product = $data['product'] ?? null;
        $variant = $data['variant'] ?? null;
        $quantity = $data['quantity'] ?? 1;

        if (!$product) {
            return false;
        }

        $stock = $variant ? $variant->stock_quantity : $product->stock_quantity;
        return $stock >= $quantity;
    }

    private function cartItemValid(array $data): bool
    {
        $product = $data['product'] ?? null;
        $variant = $data['variant'] ?? null;

        if (!$product || !$product->is_active) {
            return false;
        }

        if ($variant && (!$variant->is_active || $variant->stock_quantity <= 0)) {
            return false;
        }

        return true;
    }
}
